As a grand extension to a project we started in school, I decided I would attempt to create a visual chess game. Unsurprisingly, this was my hardest project yet, however I gained a much better understanding of classes, inheritance and overriding subroutines. In class, we were tasked to answer questions about a very beginner chess game. This was a console based application where you could only move the pawns and knights. I used this foundation to near complete the game in a windows forms application.
Key Aspects
The general layout of the program consisted of a Game, Player, Form and Piece class along with another class for each of the six piece types (pawn, knight, rook, bishop, queen and king).
Creating the Pieces
For the pieces, a base class is used. All the other piece types will use this class to make sure they are treated the same and have similar methods and properties. Firstly the Piece class uses ‘Protected’ global variables which can be used inside the Piece class and all derivative classes (the different pieces classes). The Piece class holds many different functions for example, ‘makeMove’ or ‘checkIfMoveIsValid.’ The latter function is overridable, meaning each derivative class adjusts it to fit its requirements (the rules behind how it can move). As mention, the pawn and knight classes were already prepared and this was an excellent base to go off. All move functions required source and target coordinates. These could be used in an algorithm to ensure that the move is valid. For example, the Rook needs to ensure the source and target X values or Y values are the same and that there are no pieces in between the two. The Bishop algorithm needs to ensure the difference between the source and target X values is the same as between the source and target Y values (so move is diagonal) and again there are no pieces in between. The Queen class then combines the Rook and Bishop rules and the king uses a simple one space algorithm. I also added a rule to the Pawn class where they could move two spaces forward on their first turn – just like the game. This was my first time using overridable subroutines and I now have a great understanding of their application – I feel this was an excellent example to learn from.
Controlling the Game
The display of the application was initially a painted grid of alternating squares which is then covered by transparent picture boxes (where some have piece images in). The first thing to do is setup the board. I firstly made a two dimensional array of Pieces. I then passed specific Piece types into the appropriate starting positions. The result looks like this:
The program also asks for the player names via input boxes before instructing the users on who’s turn it is in a textbox below the game.
I then added a click event to each picture box. If nothing has been selected so far, the first picture box clicked becomes the source (and is highlighted) and the second one becomes the target. The move validation process then begins and if approved, the piece will be moved to the target. The textbox also instructs the user when they have made an invalid move (e.g. they have not selected their piece or they have not selected a valid target etc…). A move might look that this:
When a valid move has been chosen, the ‘currentTurnColour’ simply switches and now it is your opponents turn.
Programming Check
The process of programming check was actually much more difficult than I had anticipated. Not only should the program ensure check is declared when a player is put under it, it should ensure a user cannot make a move which puts themselves into check since this is an illegal move. I used two separate algorithms for this. The first was a simple ‘checkForCheck’ algorithm. This would take the board itself and the current player as arguments. From the current player, it would deduce the opponent’s colour. It would then search the board for the king of that colour and record its coordinates. After that, another search through the board would find each piece which belongs to the player given to the algorithm. The next step was to check if there was a move valid from any piece to the opponent’s king which we just located. This would be able to take the king. If there was just one piece able to do so, we can conclude that the opponent is in check and this information must be displayed.
I named the algorithm which ensures you do not put yourself in check the ‘checkMoveMyselfCheck’ function (catchy right). This function takes the current player, the board and the source and target coordinates. This algorithm firstly creates a temporary board of pieces identical to the current board. It then moves the piece to the desired target on the temporary board (which is already checked to be a valid move up until this point). After the move is complete, the same ‘checkForCheck’ algorithm is used from the opponent’s point of view to ensure that this algorithm does not put you in check. If the move is approved, it is then carried out on the real board.
The end program looks like this:
Challenges in Development
Checkmate
You may have been wondering why this was not mentioned in the key aspects of the game. This is because unfortunately I was unable to find a solution in a feasible amount of time. Again I underestimated the problem. I thought that my check functions could be used together to create a sophisticated ‘checkForCheckMate’ algorithm. This is what I spent hours doing before realizing the problem was more complicated. A king is not necessarily in check just because it is unable to move. For example, if only one piece was putting it under a ‘checkMate’ situation, another piece could potentially come in and take that piece, meaning the king was actually only under check. To program this I would have struggled. I tried different methods of solving this problem before seeking help on the Internet. Here I found complicated solutions to the problem and I realized it was much more difficult than I had thought. I also struggled to understand the solution – some parts being relatively beyond me e.g. tree searching algorithms. Unfortunately time was not on my side with this project and so I had to retire with a very nearly complete project.
Flow of the program
I actually found how the control flows through the program fairly difficult. Usually games which require two players follow a similar structure where a while loop is used to control who’s turn it is until a win condition is met. This is the same structure as the starting program we were given in school – what I based the project off. Unfortunately a loop would not work for my design. This is because this program is dependant on user inputs, specifically from the click events. Normally a while loop can be used to ask the user for an input in a controlled manner e.g. a text line input. Nothing will happen until that line is inputted. Is it less straight forward in our program since you cannot make a subroutine which tries to retrieve the user input and waits for it. The user can click on the screen at any time. You have to let the user click on where they would like to move and respond from there. If their choice is invalid, the process must be repeated. This is difficult to explain but let’s just simplify it to this: the program is controlled by the user inputs, however the program cannot control the user inputs in a fashion where a loop works well.
Areas for Future Improvement
Whilst I am proud of my work, I know that there are vast improvements to be made. I understand that this is true for all applications though and I feel I stopped at a sensible time. If I were to try and improve the chess game, this is what I would focus on:
-
Finding and implementing a good checkmate algorithm which I understand.
-
Making the algorithms much more clean and understandable – often they became messy as I rushed to implement my solution before I forgot it.
-
Potentially breaking up large subroutines into lots of smaller one – there are often repeated bits of code which could be looked at.
-
Perhaps making the game drag and drop. This would be much more user friendly than the current two click system.
-
Giving more details about the problem with an invalid move to the user. Right now terms are generally more broad and could be made much more specific e.g. “there are pieces in the way of this move.”
-
Implementing the Castling move where a player’s king and rook can swap under certain conditions.
-
Implementing a piece swap when a pawn reaches the opponent’s backline – something I completely forgot about at the time.
-
A list on the side for taken pieces.
Conclusion
Overall I feel very happy with how this project went. It still has work to be done before it is the fully programmed game, however a pretty normal, low level game of chess can be played on it. I think the interface is visually appealing and user friendly so I am happy that I could get a good front-end working with a good back-end. As I mentioned earlier, I learnt a lot more about classes and inheritance – something which I am sure will serve me well in my future programming career.